package com.lancoo.cvas.arrangecourse.coursescheduling;

import com.lancoo.cvas.arrangecourse.coursescheduling.allocatetimeslotroom.AllocateNoClashTimeslotRoom;
import com.lancoo.cvas.arrangecourse.coursescheduling.allocatetimeslotroom.AllocateTimeslotRoom;
import com.lancoo.cvas.arrangecourse.coursescheduling.assignlist.NoClashAssign;
import com.lancoo.cvas.arrangecourse.coursescheduling.assignlist.NormalAssign;
import com.lancoo.cvas.arrangecourse.entities.ClassHour;
import com.lancoo.cvas.arrangecourse.entities.TeachingClassUnit;
import com.lancoo.cvas.arrangecourse.entities.TimeslotRoom;
import com.lancoo.cvas.arrangecourse.rulecheck.RuleInit;
import com.lancoo.cvas.pojo.dto.ArrangeTeachingClassRuleDto;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Description 跨校区排课
 * @Author Fortysun
 * @Date 2023/9/21 21:40
 **/
@Slf4j
public class CrossCampusScheduling {
    //排课规则初始化对象
    RuleInit ruleInit;
    //声明冲突排课对象
    private NormalAssign noClashScheduing;

    /**
     * 构造函数，初始化按类型，处理教室课时分组列的对象，同时传递排课规则初始化对象
     * @param ruleInit 排课规则初始化类
     */
    public CrossCampusScheduling(RuleInit ruleInit) {
        this.ruleInit = ruleInit;

        //初始化，按教室类型，处理教室课时分组信息列表的对象
        //初始化排课的对象
        if (noClashScheduing == null) {
            //初始化排课使用的教室课时分配的类，分配无冲突的教室课时分组信息；
            AllocateTimeslotRoom allocateNoClashTimeslotRoom = new AllocateNoClashTimeslotRoom();
            //初始化拆班排课，需要满足的规则
            noClashScheduing = new NoClashAssign(ruleInit.getCrossCampusRule(), allocateNoClashTimeslotRoom);
        }
    }

    /**
     * 开始校区冲突排课
     * @param taskId 排课选课计划id
     * @param leaveList 剩余未处理的排课教学班单元列表信息
     * @param timeslotRoomList 教室课时分组
     * @param classHourMap 已排的正常课程，转换过来的排课单元map对象，key为timeslotCode
     * @return
     */
    public LinkedList<TeachingClassUnit> start(Integer taskId,
                                               LinkedList<TeachingClassUnit> leaveList,
                                               LinkedList<TimeslotRoom> timeslotRoomList,
                                               ConcurrentHashMap<String, CopyOnWriteArrayList<ClassHour>> classHourMap) {

        //第三轮排课
        if (leaveList != null && !leaveList.isEmpty()) {
            log.info("#CrossCampusScheduling.start#--开始进行跨校区排课，不启用基础规则过滤，"
                            +"剩余教学班排课单元数量：" + (leaveList!=null?leaveList.size():0)
                            +"可用教室课时分组数量：="+ (timeslotRoomList!=null?timeslotRoomList.size():0));
            //开启第三轮冲突排课，只检测跨校区规则、禁排规则。
            //同时冲突排课，需要满足分配给教学班的教室课时分组对象的可分配周次，至少要一半或者以上，能够匹配上教学班的周次
            leaveList = noClashScheduing.start(taskId, null, leaveList, timeslotRoomList, classHourMap,new ArrayList<>());
            log.info("#CrossCampusScheduling.start#--跨校区排课结束，"
                            +"剩余教学班排课单元数量：" + (leaveList!=null?leaveList.size():0)
                            +"可用教室课时分组数量：" + (timeslotRoomList!=null?timeslotRoomList.size():0));
        }

        return leaveList;
    }
}
